// Programme for stuck-at fault detection in Tree-structured combinational logic
#include	<stdio.h>
#include	<stdlib.h>
#include    <iostream>
#include	<string.h> /*  for length function. */

using namespace std;
 /* Algorithm: Each node is represented by a boolean equation in terms of variables in previous level.
 So we need first to define input array. Each logic gate would form a struct.*/
 
 
 //We first try to get a good hold on reading Tree-structured combinational logic.
 

  struct gate{
       // vector<wire> A; // we dont know the number inputs to this gate. We might require struc like case for inputs and nodes
       // wire o;// the only thing we know is that the output is some boolean function of all the input
       char f;// OR=o, AND=a, NOR=r, NAND=d, XOR=x, NOT=t
       // o=f(A);   // each gate is representated by a function.
       int no_input;
                 };
 struct wire{
          int fault=0;//0 if absent
              //1 if stuck-at-0 fault present.
              //2 if stuck-at-1 fault present.
          gate * input_gate;// input of wire is output of this gate
          gate * output_gate;// the output of this wire goes to this gate
          int value=2;// can be either 1 or zero. default 2 implies that no value has been assigned.
          };
 
      
      

gate readgate(){
      gate temp;
      
      cout<<"number of inputs"<<endl;
      cin>>temp.no_input;
      cout<<"enter the type of logical function gate is going to perform"<<endl;
      cout<<"OR=o, AND=a, NOR=r, NAND=d, XOR=x, NOT=t"<<endl;
      cin>>temp.f;
      return temp;
      }
wire  readwire(){
      wire temp;
      int n=-1;
      int m=-1;
      cout<<"enter the gate of which this wire is output, '-1' if there is no such gate"<<endl;
      cin>>n;//assuming that the gate numbering starts from 1
      if (n==-1)
      temp.input_gate= NULL;// implies that this is primary input to the circuit
      else
      temp.input_gate= &logic[n-1];
      cout<<"enter the gate of which this wire is input, '-1' if there is no such gate"<<endl;;

      cin>>m;
      if (m==-1)
      temp.output_gate= NULL;
      else
      temp.output_gate= &logic[n-1];// Logic array of gates is not identified in this function. Might require global defination.
      
      int fault_temp=0;
      cout<<"press if te circuit has any fault. 0 for stuck-at-0, 1 for stuck-at-1, 2 for no fault"<<endl;
      cin>> fault_temp;
      temp.fault=fault_temp;
      
      return temp;
      }
      
      
int main()
{
    int no_gate=0;
    int no_wire=0;
    wire node[no_wire];
    gate logic[no_gate];
    
    //read gates
    for (int i=0; i<no_gate; i++)
    {logic[i]=readgate();}
    //read wire
    for (int i=0; i<no_wire;i++)
    {node[i]=readwire();}
    
    // check which of the wire has fault. start the excitation from that point.
    
    
//exciation
int check=0;
 for (int i=0; i<no_wire;i++)
    { check=i;
          if (node[i].fault < 2) //fault exists
    break;}
    //at this point node[check] has a fault
    
    if(node[check].fault=0)//stuck-at-0 faul
    node[check].value=1;//it is D condition
    else
    node[check].value=0;// it is D- condition
    
//implication.
// make sure that all the inputs are properly included.



//finding the gate which has this fault wire as output
//node[check].input_gate    //pointer to input gate

// We need to find inputs to this gate.
// the value of this wires should be such that it should satisfy the excitation condition.

//considering all possible cases

switch(node[check].input_gate.f){
                                 case 'o'://OR gate
                                 if(node[check].value==0)
                                 for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=0;
                                                 break;}
                                                 }
                                                 }
                                 else if (node[check].value==1)
                                  for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=1;
                                                 break;}
                                                 }
                                                 }
                                             
                                 break;
                                 case 'a'://and gate
                                  if(node[check].value==0)
                                 for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=0;
                                                 break;}
                                                 }
                                                 }
                                 else if (node[check].value==1)
                                  for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=1;
                                                 break;}
                                                 }
                                                 }
                                 break;

                                 case 'r'://nor gate
                                   if(node[check].value==0)
                                 for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=1;
                                                 break;}
                                                 }
                                                 }
                                 else if (node[check].value==1)
                                  for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=0;
                                                 break;}
                                                 }
                                                 }
                                                 
                                 break;
                                 case 'd'://nand gate
                                  if(node[check].value==0)
                                 for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=1;
                                                 break;}
                                                 }
                                                 }
                                 else if (node[check].value==1)
                                  for(int j=0; j<node[check].input_gate.n; j++){
                                         for (int i=0; i<no_wire; i++){
                                             if(node[i].output_gate == node[check].input_gate)
                                                {node[i].value=0;
                                                 break;}
                                                 }
                                                 }
                                 break;
                                 case 't'://Not gate
                                 //find for the input wire to the gate
                                 for (int i=0;i<no_wire;i++){
                                         if(node[i].output_gate == node[check].input_gate)
                                         {node[i].value= ~node[check].value;
                                         break;}
                                         }
                                 break;
                                 case 'x'://XOR gate
                                 //will have to consider if the number of inputs are even or odd
                                 if (node[check.value %2 ==0)
                                 
                                 break;
    
    int a=1; 
int b=1;
int c=a+b;
cout<<c;
while(1)
{ ;}
return 0;


} 
 // For now we assume that we are feeding the function type of the gate manually. We also need information about the wire on which fault is to
 //be detected. So does that mean that we would also have to have wire as some kind of struct. I think not. What we can do is that instead of having
 //nodes we could have only wires. So we just connect output of one wire to another. Wire will have property of 'fault presence' and its 'type'
 //It would be then very easy to develope a test for particular fault.
 
 // Suppose that one of the wire has considered as having a specific fault. Fault will have three types: nil, stuck-at-0 and stuck-at-1.
 //  Should we enter data as per gates or should we enter it using wire. I think it should be gate. After this is done we would get two lists 
 //Pne for gate and another for wires. This should be pointer from one one node to another. At end we will also get total number of gate and 
 // total number wires.  
 
 //identifying input and output: A wire will typically have two gates connected. One of the gate will provide the inputs and other 
 //shall provide the output. If input gate is null then the wire belongs to input and if the output gate is null then the wire belong to output.
 //depending on the number of wires that donnot have input gate we can get total number of inputs. similarly we can get total number of outputs.
 
 // finding a sensitization path:
 // The data that shall be given is the name or pointer of wire that has fault and type of fault. For other wire the type of fault shall be nill.
 // Here we can follow the same algorithm that is followed in the book.
 
 // Algorithm given in book.
 
 /* 1. Finding an excitaion condition */
 check which wire has fault.
 add excitaion condition. Make the wire value to be opposite of the stuck at value.
 
 /* 2. Implication of the last assignment */
 We have to make sure that the excitation reaches the output.
 This will have hardcode algorithm for each case.
 forward(){
 OR: for implication to reach to output other inputs have to zero.
 AND: Other inputs should be one.
 NOR : Other inputs have to zero
 NAND : Other inputs have to be one.
 NOT: No need for any changes!!.
 XOR: other inputs should be used such that they cancel the effect. First we need to calculate number of inputs.
 If the number of other inputs is odd then we could tranfer invert of the excitaional. If the number is even we could tranfer the excitaion to output.
}


//thils function will be called iteratively various number of times.
//should decide the arguments of the fucntion.



 
 /* 3. Check if the implication has reached output; justify unjustified lines */ 
 Continuing this method the implication may or may not reach the output. If it reached output we try to justify the lines which have been
 not yet assigned a value.  and how do we that?
 We randomnly assign input values which have not yet been assigned. Try to get remaining values. If it agrees with previously assigned 
 values(No contradiction). ############I dont see point of this thing not working#########
 /* No output reached.. go back and look at implication*/
 
 /* frontier with only one gate.*/
 
 There may be still wires which has nothing to do with fault site. No relation. For this type of wire we need to random assignments. 
 Make a decision tree for these left wires till they satisty the condition. Now check if all the wires are assigned.
  Test got!!
  
 If no out

 This would call for a decision diagram. we have to chose a particular wire assigne it some value such that present cases are not violated.
 Chose another variable. Each time check for feasibility. It is possible new assignment do not contradict previous assignments.
If there is any problem with assginment go back and  change the value of latest wire and continue. If still the assignment is contradicting go to next 
latest wire and change the assignment.  

For performing this we need ordering the valriables. I dont know how are we going to order these variables. Suppose if we start from output 
it might be easy to backtrack. We can look at the outputs. Choose output which has not been yet assigned any value. Trace it back till the 
inputs using this technique. Even this function needs to be iterative. 
 
 /* 4. 
  Ok but these people are talking in terms of frontier*/ 
int main()
{int a=1; 
int b=1;
int c=a+b;
cout<<c;
while(1)
{ ;}
return 0;


}
